<template>
  <el-dialog
    v-model="dialogVisible"
    title="导入自定义组件"
    width="600px"
    :before-close="handleClose"
    :close-on-click-modal="false"
  >
    <el-tabs v-model="activeTab">
      <!-- 通过文件导入 -->
      <el-tab-pane label="选择本地文件" name="file">
        <div class="file-upload-container">
          <el-upload
            class="upload-demo"
            drag
            action=""
            :auto-upload="false"
            :on-change="handleFileChange"
            :limit="1"
            accept=".vue"
            :file-list="fileList"
          >
            <el-icon class="el-icon--upload"><upload-filled /></el-icon>
            <div class="el-upload__text">
              拖放 Vue 组件文件到此处，或<em>点击选择</em>
            </div>
            <template #tip>
              <div class="el-upload__tip">
                只能上传 .vue 文件，且组件需要符合规范
              </div>
            </template>
          </el-upload>
        </div>
      </el-tab-pane>

      <!-- 通过目录导入 -->
      <el-tab-pane label="指定目录扫描" name="directory">
        <div class="directory-scan-container">
          <p>您可以将自定义组件放入以下目录，系统将自动扫描并加载：</p>
          <el-alert
            title="dynamic-components/"
            type="info"
            description="项目根目录下的 dynamic-components 文件夹"
            :closable="false"
            show-icon
          />
          <div class="scan-actions">
            <el-button 
              type="primary" 
              @click="handleScanDirectory"
              :disabled="isScanningDirectory"
              :loading="isScanningDirectory"
            >立即扫描目录</el-button>
          </div>
        </div>
      </el-tab-pane>
    </el-tabs>

    <!-- 组件信息表单 -->
    <div v-if="fileSelected" class="component-form">
      <h3>组件信息</h3>
      <el-form 
        ref="formRef"
        :model="componentForm"
        :rules="formRules"
        label-width="80px"
        label-position="right"
        size="default"
      >
        <el-form-item label="名称" prop="name">
          <el-input v-model="componentForm.name" placeholder="输入组件名称" />
        </el-form-item>
        <el-form-item label="类型" prop="type">
          <el-input v-model="componentForm.type" placeholder="输入组件类型标识符" />
          <div class="form-helper-text">类型标识符用于在设计器中识别组件，如 my-button</div>
        </el-form-item>
        <el-form-item label="分类" prop="category">
          <el-select v-model="componentForm.category" placeholder="选择组件分类" style="width: 100%;">
            <el-option label="基础组件" value="basic" />
            <el-option label="容器组件" value="container" />
            <el-option label="表单控件" value="form" />
            <el-option label="数据展示" value="data" />
            <el-option label="导航组件" value="navigation" />
            <el-option label="反馈组件" value="feedback" />
            <el-option label="其他" value="other" />
          </el-select>
        </el-form-item>
        <el-form-item label="版本" prop="version">
          <el-input v-model="componentForm.version" placeholder="如: 1.0.0" />
        </el-form-item>
        <el-form-item label="作者" prop="author">
          <el-input v-model="componentForm.author" placeholder="(可选) 输入作者名称" />
        </el-form-item>
        <el-form-item label="描述" prop="description">
          <el-input 
            v-model="componentForm.description" 
            type="textarea" 
            rows="3"
            placeholder="(可选) 输入组件描述" 
          />
        </el-form-item>
        <el-form-item label="图标" prop="icon">
          <el-select 
            v-model="componentForm.icon" 
            placeholder="(可选) 选择组件图标"
            filterable
            style="width: 100%;"
          >
            <el-option label="(无图标)" value="" />
            <el-option
              v-for="icon in availableIcons"
              :key="icon.name"
              :label="icon.name"
              :value="icon.name"
            >
              <div class="icon-option">
                <el-icon><component :is="icon.name" /></el-icon>
                <span>{{ icon.name }}</span>
              </div>
            </el-option>
          </el-select>
        </el-form-item>
      </el-form>
    </div>

    <template #footer>
      <span class="dialog-footer">
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button
          type="primary"
          :disabled="!fileSelected || importing"
          :loading="importing"
          @click="handleImport"
        >
          导入组件
        </el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, computed, watch, defineProps, defineEmits, onMounted } from 'vue';
import { UploadFilled } from '@element-plus/icons-vue';
import componentLoader from '@/utils/componentLoader';
import { ElMessage, type FormInstance, type FormRules, type UploadFile } from 'element-plus';
import * as ElementPlusIconsVue from '@element-plus/icons-vue';

// Props & Emits
const props = defineProps<{
  visible: boolean;
}>();

const emit = defineEmits<{
  (e: 'update:visible', value: boolean): void;
  (e: 'import-success', componentId: string): void;
}>();

// 内部状态
const dialogVisible = ref(props.visible);
const activeTab = ref('file');
const fileList = ref<UploadFile[]>([]);
const fileSelected = ref(false);
const importing = ref(false);
const isScanningDirectory = ref(false);
const formRef = ref<FormInstance>();

// 同步 prop 与内部状态
watch(() => props.visible, (newVal) => {
  dialogVisible.value = newVal;
  if (!newVal) {
    resetForm();
  }
});

watch(() => dialogVisible.value, (newVal) => {
  emit('update:visible', newVal);
});

// 获取所有可用图标
const availableIcons = ref<{ name: string }[]>([]);

onMounted(() => {
  // 获取 Element Plus 所有图标
  availableIcons.value = Object.keys(ElementPlusIconsVue)
    .filter(name => name !== 'default') // 排除 default 导出
    .map(name => ({ name }));
});

// 表单数据
const componentForm = ref({
  name: '',
  type: '',
  category: 'basic',
  version: '1.0.0',
  author: '',
  description: '',
  icon: ''
});

// 表单验证规则
const formRules: FormRules = {
  name: [
    { required: true, message: '请输入组件名称', trigger: 'blur' },
    { min: 2, max: 30, message: '长度应为2到30个字符', trigger: 'blur' }
  ],
  type: [
    { required: true, message: '请输入组件类型标识符', trigger: 'blur' },
    { min: 2, max: 30, message: '长度应为2到30个字符', trigger: 'blur' },
    { 
      pattern: /^[a-z][a-z0-9-]*$/, 
      message: '类型标识符应以小写字母开头，只能包含小写字母、数字和连字符', 
      trigger: 'blur' 
    }
  ],
  category: [
    { required: true, message: '请选择组件分类', trigger: 'change' }
  ],
  version: [
    { required: true, message: '请输入版本号', trigger: 'blur' },
    { 
      pattern: /^\d+\.\d+\.\d+$/, 
      message: '版本号格式应为：x.y.z，如 1.0.0', 
      trigger: 'blur' 
    }
  ]
};

// 处理文件变更
const handleFileChange = (file: UploadFile) => {
  if (file.raw?.type !== 'text/x-vue' && !file.name.endsWith('.vue')) {
    ElMessage.error('只能上传 Vue 组件文件!');
    fileList.value = [];
    fileSelected.value = false;
    return;
  }
  
  fileList.value = [file];
  fileSelected.value = true;
  
  // 尝试从文件名中提取组件信息
  const fileName = file.name.replace('.vue', '');
  if (fileName && componentForm.value.name === '') {
    // 将文件名转换为合适的组件名称
    // 例如：my-button.vue -> My Button
    const formattedName = fileName
      .split('-')
      .map(word => word.charAt(0).toUpperCase() + word.slice(1))
      .join(' ');
    
    componentForm.value.name = formattedName;
    
    // 设置类型标识符
    componentForm.value.type = fileName.toLowerCase();
  }
};

// 扫描目录
const handleScanDirectory = () => {
  isScanningDirectory.value = true;
  
  setTimeout(() => {
    ElMessage.info('目录扫描功能正在开发中，将在后续版本支持');
    isScanningDirectory.value = false;
  }, 1000);
};

// 导入组件
const handleImport = async () => {
  if (!fileSelected.value || !fileList.value[0]) {
    ElMessage.warning('请先选择组件文件');
    return;
  }
  
  // 表单验证
  const valid = await formRef.value?.validate();
  if (!valid) {
    return;
  }
  
  importing.value = true;
  
  try {
    const file = fileList.value[0].raw;
    if (!file) {
      throw new Error('文件获取失败');
    }
    
    // 在实际应用中，这里需要使用 API 上传文件，然后获取文件路径
    // 由于我们无法直接处理文件系统，这里模拟文件路径
    const mockFilePath = `dynamic-components/${file.name}`;
    
    // 从表单中获取组件信息
    const result = await componentLoader.loadComponentFromFile(mockFilePath, {
      name: componentForm.value.name,
      type: componentForm.value.type,
      category: componentForm.value.category,
      version: componentForm.value.version,
      author: componentForm.value.author,
      description: componentForm.value.description,
      icon: componentForm.value.icon || undefined
    });
    
    if (result.success && result.componentId) {
      ElMessage.success(`组件 ${componentForm.value.name} 导入成功`);
      emit('import-success', result.componentId);
      dialogVisible.value = false;
    } else {
      ElMessage.error(`导入失败: ${result.message}`);
    }
  } catch (error) {
    console.error('组件导入失败:', error);
    ElMessage.error(`组件导入失败: ${error instanceof Error ? error.message : String(error)}`);
  } finally {
    importing.value = false;
  }
};

// 重置表单
const resetForm = () => {
  formRef.value?.resetFields();
  fileList.value = [];
  fileSelected.value = false;
  activeTab.value = 'file';
  componentForm.value = {
    name: '',
    type: '',
    category: 'basic',
    version: '1.0.0',
    author: '',
    description: '',
    icon: ''
  };
};

// 关闭对话框
const handleClose = () => {
  dialogVisible.value = false;
};
</script>

<style scoped>
.file-upload-container,
.directory-scan-container {
  padding: 20px 0;
}

.component-form {
  margin-top: 20px;
  border-top: 1px solid #ebeef5;
  padding-top: 20px;
}

.component-form h3 {
  margin-top: 0;
  margin-bottom: 20px;
  font-size: 16px;
  color: #303133;
}

.form-helper-text {
  font-size: 12px;
  color: #909399;
  margin-top: 4px;
}

.icon-option {
  display: flex;
  align-items: center;
}

.icon-option .el-icon {
  margin-right: 8px;
  font-size: 16px;
}

.scan-actions {
  margin-top: 20px;
  text-align: center;
}

.directory-scan-container p {
  margin-bottom: 15px;
  font-size: 14px;
  color: #606266;
}
</style> 